import re

from selenium.webdriver.common.keys import Keys
from selenium.webdriver.remote.webelement import WebElement

from .multiple import run_multiple_operation
from utils.selenium.perform import WPerform


class KeyboardOptionType:
    SET_DATA = 1
    BACK_SPACE = 2
    SPACE = 3
    TAB = 4
    ESCAPE = 5
    ENTER = 6
    CONTROL_A = 7
    CONTROL_C = 8
    CONTROL_V = 9
    CONTROL_X = 10


class NumericalType:
    VALUE = 1
    SEARCH = 2


class InterceptionType:
    """数值类型"""
    trim = 1  # 过滤两侧空格
    location = 2  # 查询到的数据
    with_end = 3  # 指定位置到结束
    start_with = 4  # 开始到指定位置
    regular = 5  # 正则


def get_numerical(perform: WPerform, item):
    """获取值"""
    numerical_type = item.get('numerical_type')
    if numerical_type == NumericalType.VALUE:
        return item.get('numerical')
    numerical_search: dict = item.get('numerical_search')
    if not numerical_search:
        raise Exception("请设置查询参数")
    perform.send_msg('查询【%s】的值' % numerical_search.get('name'))
    find_type = numerical_search.get('find_type')
    find_key = numerical_search.get('find_key')
    find_multiple = numerical_search.get('find_multiple')
    find_multiple_index = numerical_search.get('find_multiple_index', 1) - 1
    is_filter_hide_element = numerical_search.get('is_filter_hide_element')
    element: WebElement = perform.fint(find_type=find_type, find_key=find_key, multiple=find_multiple, find_index=find_multiple_index, is_filter_hide_element=is_filter_hide_element)
    interception_type = numerical_search.get('interception_type')
    text: str = element.text
    if not interception_type:
        return text
    if interception_type == InterceptionType.trim:
        return text.lstrip().rstrip()
    elif interception_type == InterceptionType.location:
        location = numerical_search.get('location')
        length = numerical_search.get('length')
        return text[location:(location + length)]
    elif interception_type == InterceptionType.start_with:
        location = numerical_search.get('location')
        return text[:location]
    elif interception_type == InterceptionType.with_end:
        location = numerical_search.get('location')
        return text[location:]
    elif interception_type == InterceptionType.regular:
        regular = numerical_search.get('regular')
        reg_data = re.compile(regular).match(text)
        return reg_data.group()


def run_keyboard_operation(perform: WPerform, item: dict, other_query: dict):
    """
    执行键盘操作
    :param driver: 页面的 driver
    :param item: 用例数据
    :param other_query: 顶层带过来的额外参数
    :return:
    """
    keyboard_option_type = item.get('keyboard_option_type')
    if keyboard_option_type == KeyboardOptionType.SET_DATA:
        numerical = get_numerical(perform, item)
        run_multiple_operation(perform, item, 'send_keys', (numerical,), other_query)
    elif keyboard_option_type == KeyboardOptionType.BACK_SPACE:
        run_multiple_operation(perform, item, 'send_keys', (Keys.BACK_SPACE,), other_query)
    elif keyboard_option_type == KeyboardOptionType.SPACE:
        run_multiple_operation(perform, item, 'send_keys', (Keys.SPACE,), other_query)
    elif keyboard_option_type == KeyboardOptionType.TAB:
        run_multiple_operation(perform, item, 'send_keys', (Keys.TAB,), other_query)
    elif keyboard_option_type == KeyboardOptionType.ESCAPE:
        run_multiple_operation(perform, item, 'send_keys', (Keys.ESCAPE,), other_query)
    elif keyboard_option_type == KeyboardOptionType.ENTER:
        run_multiple_operation(perform, item, 'send_keys', (Keys.ENTER,), other_query)
    elif keyboard_option_type == KeyboardOptionType.CONTROL_A:
        run_multiple_operation(perform, item, 'send_keys', (Keys.CONTROL, 'a'), other_query)
    elif keyboard_option_type == KeyboardOptionType.CONTROL_C:
        run_multiple_operation(perform, item, 'send_keys', (Keys.CONTROL, 'c'), other_query)
    elif keyboard_option_type == KeyboardOptionType.CONTROL_V:
        run_multiple_operation(perform, item, 'send_keys', (Keys.CONTROL, 'v'), other_query)
    elif keyboard_option_type == KeyboardOptionType.CONTROL_X:
        run_multiple_operation(perform, item, 'send_keys', (Keys.CONTROL, 'x'), other_query)